/*
 * TPM_interface.c
 *
 *  Created on: Sep 17, 2013
 *      Author: uidu9161
 */


#include "derivative.h" /* include peripheral declarations */
#include "TPM_interface.h"
#include "Sw_Timers.h"



TPM_tdErrorNum TPM_Init (TPM_MemMapPtr TPMmodule,TPM_tdCLKsrc tdCKLsrc ,uint32 u32clk_khz, uint32 u32Tick_khz) 
{	
	//uint32 u32Prescaler[7] = 0;
	//uint8 u8PrescalerSelect = 0;
	//uint8 u8PrescalerValue = 0;
	
	/* Select TPM clock source */
	SIM_SOPT2 |= SIM_SOPT2_TPMSRC(tdCKLsrc); 	
	/* Enable Clock for indicated TPM module */
	if(TPM__nTPM0 == TPMmodule)
	{
		SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;
	}
	else if (TPM__nTPM1 == TPMmodule)
	{
		SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK;
	}
#ifdef TPM2_BASE_PTR
	else if (TPM__nTPM2 == TPMmodule)
	{
		SIM_SCGC6 |= SIM_SCGC6_TPM2_MASK;
	}
#endif

//************************************************************************************************************************//

	/*
	if(u32clk_khz > u32Tick_khz)
	{
		u32Prescaler[0]	= u32clk_khz/2;
		u32Prescaler[1] = u32clk_khz/4;
		u32Prescaler[2] = u32clk_khz/8;
		u32Prescaler[3] = u32clk_khz/16;
		u32Prescaler[4] = u32clk_khz/32;
		u32Prescaler[5] = u32clk_khz/64;
		u32Prescaler[6] = u32clk_khz/128;
		
		for (i=0; i<7; i++)
		{
			if(u32Prescaler[i] <= u32Tick_khz )
			{
				u8PrescalerSelect = i;
			}
			else
			{
			
			}
		}		
		switch(u8PrescalerSelect)
		{
		case 0:
			u8PrescalerValue = TPM__nDiviby2;
			break;
		case 1:
			u8PrescalerValue = TPM__nDiviby4;
			break;
		case 2:
			u8PrescalerValue = TPM__nDiviby8;
			break;
		case 3:
			u8PrescalerValue = TPM__nDiviby16;
			break;
		case 4:
			u8PrescalerValue = TPM__nDiviby32;
			break;
		case 5:
			u8PrescalerValue = TPM__nDiviby64;
			break;
		case 6:
			u8PrescalerValue = TPM__nDiviby128;
			break;
		default:
			break;
		}
		
	}
	else
	{
		//Error, CLK should be bigger than tick
		return TPM_enNoValidParam;
	}
	*/
//************************************************************************************************************************//
	TPM_SC_REG(TPMmodule) |= TPM_SC_TOIE_MASK; 		/* Enable TOF interrupts */
	TPM_SC_REG(TPMmodule) |= TPM_SC_PS(0x04);		/* Set prescaler to divide by 16*/
	TPM_SC_REG(TPMmodule) |= TPM_SC_CMOD(0x01); 	/* Counter increments on every TPM counter clock */
	
	
	
	TPM_MOD_REG(TPMmodule) = 0x05F4; 			/*Set the mod register to reach 1 ms mod=1524*/
	TPM_CnSC_REG(TPMmodule,0x00) = 0x30;		/*TPM0 channel 0 mode software compare */
	
	/* Reset counter value */
	TPM_CNT_REG(TPMmodule) = 0;
	
	return 0;
}

/*ToDo: Correct this shit from freescale */
void TPM_init_PWM(TPM_MemMapPtr TPMx, int  clock_source, int module, int clock_mode, int ps, int counting_mode)
{
   if(TPMx == TPM0_BASE_PTR)
      SIM_SCGC6   |= SIM_SCGC6_TPM0_MASK;
   else if(TPMx == TPM1_BASE_PTR)
      SIM_SCGC6   |= SIM_SCGC6_TPM1_MASK;
   
   SIM_SOPT2   |= SIM_SOPT2_TPMSRC(clock_source);
   
   TPM_MOD_REG(TPMx)    =  module;
   
   TPM_SC_REG(TPMx)  |= TPM_SC_CMOD(clock_mode) | TPM_SC_PS(ps);
   
   if(counting_mode)
      TPM_SC_REG(TPMx) |= TPM_SC_CPWMS_MASK;
}

void TPM_CH_init(TPM_MemMapPtr TPMx, int channel, int mode)
{
   TPM_CnSC_REG(TPMx, channel) |= mode;
}

void set_TPM_CnV(TPM_MemMapPtr TPMx, int channel, int value)
{
   TPM_CnV_REG(TPMx, channel) = value;
}



void TPM0_IRQHandler(void)
{	
	if((TPM0_STATUS & TPM_STATUS_TOF_MASK) == 
			TPM_STATUS_TOF_MASK)
	{
		TPM0_STATUS = TPM_STATUS_TOF_MASK;
		TPM__TPM0_ISR();	
	}	
}
